package org.totoro.lambda;

import org.junit.Test;

import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.DoubleConsumer;
import java.util.function.Function;
import java.util.function.IntBinaryOperator;
import java.util.function.IntFunction;
import java.util.function.IntPredicate;
import java.util.function.IntSupplier;
import java.util.function.ObjDoubleConsumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;


/**
 * @author YHL
 * @version V1.0
 * @Description: Lambda 表达式
 * @date 2019-01-14
 */
public class LambdaExpressionTest {


    /**
     * Consumer<T> – 在入参T上执行一个操作，无返回结果。
     *
     * @see java.util.function.Consumer
     * <p>
     * 限制入参参数类型
     * @see java.util.function.DoubleConsumer
     * @see java.util.function.IntConsumer
     * @see java.util.function.LongConsumer
     * <p>
     * <p>
     * 两个参数
     * 第一个入参可以是泛型，第二个入参指定类型 例如  int、double、long 等
     * @see java.util.function.ObjDoubleConsumer
     * @see java.util.function.ObjIntConsumer
     * @see java.util.function.ObjLongConsumer
     */
    @Test
    public void ConsumerTest() {

        /**
         * 一个泛型入参
         */
        Consumer<String> tConsumer = e -> {
            System.out.println("你好 》 " + e);
        };

        tConsumer.accept("张三");

        /**
         * 限制参数类型
         */
        DoubleConsumer doubleConsumer = e -> {
            System.out.println(e);
        };

        doubleConsumer.accept(1.0);


        /**
         * 入参两个入参
         */
        BiConsumer<String, String> t = (e1, e2) -> {
            System.out.println("我来自： " + e1 + "     " + e2);
        };

        t.accept("湖南", "长沙");

        ObjDoubleConsumer<String> objDoubleConsumer = (e1, e2) -> {

            System.out.println(e1 + "分数：" + e2);
        };

        objDoubleConsumer.accept("张三", 88.0);

    }

    /**
     * 无输入参数，返回T的实例
     *
     * @see java.util.function.Supplier
     * <p>
     * 限制 返回类型
     * @see java.util.function.IntSupplier
     * @see java.util.function.DoubleSupplier
     * @see java.util.function.LongSupplier
     * @see java.util.function.BooleanSupplier
     */
    @Test
    public void SupplierTest() {

        /**
         * 泛型
         */
        Supplier<String> supplier = () -> {

            return "张三";
        };

        System.out.println(supplier.get());

        /**
         * *-*-*-*-**-*-*-*-**-*-*-*-**-*-*-*-**-*-*-*-**-*-*-*-**-*-*-*-**-*-*-*-*
         * 限定类型
         */
        IntSupplier intSupplier = () -> {
            return 1;
        };

        System.out.println("result:" + intSupplier.getAsInt());

    }


    /**
     * 输入参数为T的实例，返回boolean值
     *
     * @see java.util.function.Predicate
     * @see Predicate#and(Predicate)
     * @see Predicate#or(Predicate)
     * <p>
     * 限定入参类型 ，返回 boolean 值
     * @see java.util.function.IntPredicate
     * @see java.util.function.DoublePredicate
     * @see java.util.function.LongPredicate
     * @see java.util.function.BiPredicate
     */
    @Test
    public void PredicateTest() {

        /**
         * 泛型 参数
         * @see java.util.stream.Stream#allMatch(Predicate)
         */
        Predicate<String> predicate = e -> {
            return "张三".equals(e);
        };

        System.out.println("predicate result:" + predicate.test("张三"));

        /**
         * 限定 参数
         * *-*-*-*-**-*-*-*-**-*-*-*-**-*-*-*-**-*-*-*-**-*-*-*-**-*-*-*-**-*-*-*-*
         */

        IntPredicate intPredicate = e -> {
            return e == 10;
        };

        System.out.println("intPredicate result:" + intPredicate.test(10));

        boolean test = predicate.and(e -> {

            return !"王五".equals(e);

        }).test("张三");

        System.out.println("多个 表达式 and  ：" + test);



    }


    /**
     * 泛型入参，泛型出参
     *
     * @see java.util.function.Function –输入参数为T的实例，返回R的实例
     * <p>
     * 限定出参
     * @see java.util.function.IntFunction
     * @see java.util.function.DoubleFunction
     * @see java.util.function.LongFunction
     * <p>
     * 限定入参和出参
     * @see java.util.function.DoubleToIntFunction
     * @see java.util.function.DoubleToLongFunction
     * @see <p>
     * 多个 入参
     * @see java.util.function.BiFunction
     * <p>
     * 两个参数,并且限定出参
     * @see java.util.function.ToIntBiFunction
     * @see java.util.function.ToDoubleBiFunction
     * @see java.util.function.ToLongBiFunction
     */
    @Test
    public void FunctionTest() {

        /**
         * 泛型
         */
        Function<Character, Integer> function = e -> {
            return (int) e.charValue();
        };

        Integer result = function.apply('好');
        System.out.println("function result:" + result);


        /**
         * 限定入参
         */
        IntFunction<Character> intFunction = e -> {
            return (char) e;
        };

        System.out.println("intFunction result : " + intFunction.apply(result));


        /**
         * 两个入参
         */
        BiFunction<String, Integer, String> biFunction = (e1, e2) -> {

            if ("张三".equals(e1) && e2 > 20) {
                return "名字正确，并且已成年";
            }

            return "输入不正确";

        };

        String biFunctionResult = biFunction.apply("张三", 25);

        System.out.println("biFunctionResult result:" + biFunctionResult);
    }


    /**
     * 2个泛型入参和泛型出参
     *
     * @see java.util.function.BinaryOperator
     * <p>
     * 限定参数
     * @see java.util.function.IntBinaryOperator
     * @see java.util.function.DoubleBinaryOperator
     * @see java.util.function.LongBinaryOperator
     * <p>
     * 单个入参
     * @see java.util.function.UnaryOperator
     */
    @Test
    public void BinaryOperatorTest() {

        /**
         * 泛型参数
         * @see java.util.stream.Stream#reduce(BinaryOperator)
         */
        BinaryOperator<String> binaryOperator = (l, r) -> {
            return l + r;
        };

        String apply = binaryOperator.apply("李四", "王五");

        System.out.println("binaryOperator result：" + apply);

        /**
         * 限定参数
         */
        IntBinaryOperator intBinaryOperator = (e1, e2) -> {
            return e1 - e2;
        };

        System.out.println("intBinaryOperator result：" + intBinaryOperator.applyAsInt(20, 50));


        /**
         * 单个参数
         *
         * @see java.util.stream.Stream#map(Function)
         */

        UnaryOperator<String> unaryOperator = e -> {
            return "";
        };


    }

}
